package com.gardeneaters.game_v0.playingfield;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.CssColor;

public class Garden {

	private Hexagon [][] hexagons;
	private int NumOfHexX = 20;//24
	private int NumOfHexY = 14;//18
	private int hexWidth, hexHeight, overlap;
	//MushroomGroup blueMshrm;
	private Context2d context, backBuffer;
	private int canvasWidth, canvasHeight;
		
	public Garden(Context2d _context){
		this.context = _context;
		this.canvasHeight = context.getCanvas().getHeight();
		this.canvasWidth = context.getCanvas().getWidth();
		Canvas backBufferCanvas = Canvas.createIfSupported();
	    backBufferCanvas.setCoordinateSpaceWidth(_context.getCanvas().getWidth());
	    backBufferCanvas.setCoordinateSpaceHeight(_context.getCanvas().getHeight());
	    backBuffer = backBufferCanvas.getContext2d();
	    
	//	blueMshrm = new MushroomGroup(100,100,2);

        createHexagons();
        backBuffer.drawImage(context.getCanvas(), 0, 0);// saving 'context' so we don't have to do all that processing again
	}
	
	public void createGarden(){
		this.canvasHeight = context.getCanvas().getHeight();
		this.canvasWidth = context.getCanvas().getWidth();
		//context.setFillStyle(CssColor.make("rgba(255,255,255,1)"));
		//context.fillRect(0,0,canvasWidth,canvasHeight);
		redrawHexagons();
		backBuffer.drawImage(context.getCanvas(), 0, 0);
	}
	
	private void createHexagons(){

		hexWidth = 2*canvasWidth/(2*NumOfHexX+1);
		hexHeight = canvasHeight*4/(3*NumOfHexY+2);
		overlap = hexHeight/4;

		hexagons = new Hexagon[NumOfHexY][NumOfHexX];
		
		int x=0,y=0;
		for(int i=0; i<NumOfHexY; i=i+2)
		{
			x = 0;
			for(int j =0; j<NumOfHexX; j++)
			{

				hexagons[i][j] = new Hexagon(context,x,y,hexWidth,hexHeight);
				x += hexWidth;
			}
			
			y += hexHeight - overlap;
			x = hexWidth/2;
			
			for(int j =0; j<NumOfHexX; j++)
			{

				hexagons[i+1][j] = new Hexagon(context,x,y,hexWidth,hexHeight);
				x += hexWidth;
			}
			y += hexHeight - overlap;
		}
		
	}
	
	public Hexagon[][] getHexagons(){
		return hexagons;
	}
	
	private void redrawHexagons(){
		hexWidth = 2*canvasWidth/(2*NumOfHexX+1);
		hexHeight = canvasHeight*4/(3*NumOfHexY+2);
		overlap = hexHeight/4;
		
		int x=0,y=0;
		for(int i=0; i<NumOfHexY; i=i+2)
		{
			x = 0;
			for(int j =0; j<NumOfHexX; j++)
			{
				hexagons[i][j].resize(x,y,hexWidth,hexHeight);
				x += hexWidth;
			}
			
			y += hexHeight - overlap;
			x = hexWidth/2;
			
			for(int j =0; j<NumOfHexX; j++)
			{

				hexagons[i+1][j].resize(x,y,hexWidth,hexHeight);
				x += hexWidth;
			}
			y += hexHeight - overlap;
		}
	}
	
	public void draw() {
		context.drawImage(backBuffer.getCanvas(), 0, 0);// drawing background
		
		
		
		//call draw method of hexagons but don't redraw all hexagons
		for(int i=0; i<NumOfHexY; i++)
		{
			for(int j =0; j<NumOfHexX; j++)
			{
				hexagons[i][j].draw();
			}
		}
		

	}
	
	public void click(int mouseStartX, int mouseStartY, int mouseEndX, int mouseEndY){
		//TODO remove arrow from hexagon if mouseStart and mouseEnd are same 
		int side = getHexSide( mouseStartX, mouseStartY, mouseEndX, mouseEndY);
		Hexagon hexagon = getHexagon(mouseStartX, mouseStartY);
		hexagon.point(side);
		
		
		//System.out.println(side);
//	    context.beginPath();
//	    context.arc(mouseStartX,mouseStartY, 10, 0, Math.PI * 2, true);
//	    context.closePath();
//	    context.stroke();
	   // backBuffer.drawImage(context.getCanvas(), 0, 0);
	}
	
	private Hexagon getHexagon(int mouseStartX, int mouseStartY){
		//TODO improve it.. does not work well at edges
		int tempSqrX = hexWidth;
		int tempSqrY = hexHeight-overlap;
//		System.out.println(hexWidth+"  h  "+hexHeight+"  overlap  "+overlap+" tempsqrY "+ tempSqrY);
		int y = mouseStartY/tempSqrY;
		
		if(y%2==0)// y is even
		{
			
		}
		else
		{
			mouseStartX = mouseStartX-hexWidth/2;
		}
		int x = mouseStartX/tempSqrX;

		double tempY = hexHeight*y*3/4+hexHeight*3/4-mouseStartY;
		double tempX = mouseStartX-x*hexWidth;
		//(y - y0) (x1 - x0) - (x - x0) (y1 - y0)// if less then zero then point(x,y) is to right of vector(x0y0 --> x1y1).
		int upperLeft = (int) ((tempY - hexHeight/2)*(hexWidth/2) - (tempX)*(hexHeight*3/4 - hexHeight/2));
		int upperRight = (int)((tempY-hexHeight*3/4)*(hexWidth/2)-(tempX-hexWidth/2)*(hexHeight/2-hexHeight*3/4));
		
		if(mouseStartX>0)
		{
			if(upperLeft<=0 && upperRight<=0)
			{	
				if(y<hexagons.length && x < hexagons[0].length)
					return hexagons[y][x];
			}
			else if(upperLeft>0)
			{
				if(y%2==0)
				{
					if(y>0 && x>0)
						return hexagons[y-1][x-1];
				}
				else
				{
					if(y>0)
						return hexagons[y-1][x];
				}
			}
			else
			{
				if(y%2==0)
				{
					if(y>0)
						return hexagons[y-1][x];
				}
				else
					if(y>0 && x>0)
						if(hexagons[y-1].length>x+1)
							return hexagons[y-1][x+1];
					
			}
		}
		return null;
		
	}
	
	private int getHexSide(int mouseStartX, int mouseStartY, int mouseEndX, int mouseEndY) {
		
		int x = mouseEndX - mouseStartX;
		int y = mouseEndY - mouseStartY;
		
		double angleRadian = Math.atan2(y,x);
		//System.out.println(angleRadian+ " * "+Double.compare(Math.atan(0.5),-angleRadian)+" * "+Double.compare(angleRadian,Math.atan(0.5)));
		//Double.compare(arg0, arg1)
		if(Double.compare(mouseStartX, mouseEndX)==0 && Double.compare(mouseStartY, mouseEndY)==0)
			return 0;
		else if( Double.compare(-angleRadian, Math.atan(0.5)) == 1 &&  Double.compare(Math.PI/2, -angleRadian) == 1)
			return 1;
		else if(Double.compare(Math.atan(0.5),Math.abs(angleRadian)) == 1)
			return 2;
		else if(Double.compare(angleRadian, Math.atan(0.5)) == 1 &&  Double.compare(Math.PI/2, angleRadian) == 1)
			return 3;
		else if(Double.compare(angleRadian, Math.PI/2) == 1 &&  Double.compare(Math.PI-Math.atan(0.5), angleRadian) == 1)
			return 4;
		else if( Double.compare(Math.abs(angleRadian), Math.PI-Math.atan(0.5)) == 1)
			return 5;
		else if(Double.compare(Math.PI-Math.atan(0.5),-angleRadian) == 1 &&  Double.compare(-angleRadian, Math.PI/2) == 1)
			return 6;
		return 0;
	}
	



}//End Class
